package starter.gate.netty;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.codec.LengthFieldPrepender;

import java.util.Date;
import java.util.concurrent.Executors;

import com.bowlong.tool.Lib2;
import com.bowlong.util.Log;

public class GateTcpServer extends Lib2 {
	public static Date BEGIN = new Date();
	static String NAME = "och";
	static double VER = 1.0;

	static final Runtime runtime = Runtime.getRuntime();

	public static void start(int port) {
		Executors.newCachedThreadPool();
		EventLoopGroup bossGroup = new NioEventLoopGroup();
		EventLoopGroup workerGroup = new NioEventLoopGroup();
		try {
			ServerBootstrap b = new ServerBootstrap();
			b.group(bossGroup, workerGroup)
					.channel(NioServerSocketChannel.class)
					.option(ChannelOption.TCP_NODELAY, true)
					.option(ChannelOption.SO_KEEPALIVE, true)
					.option(ChannelOption.SO_BACKLOG, 128)
					.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 3000)
					.childHandler(new ChannelInitializer<SocketChannel>() {
						@Override
						public void initChannel(SocketChannel ch)
								throws Exception {
							ChannelPipeline pipeline = ch.pipeline();
							int MAX_LENGTH = Short.MAX_VALUE * 2;
							LengthFieldBasedFrameDecoder dec = new LengthFieldBasedFrameDecoder(
									MAX_LENGTH, 0, 2, 0, 2);
							LengthFieldPrepender enc = new LengthFieldPrepender(
									2);
							pipeline.addLast("frameDecoder", dec);
							pipeline.addLast("frameEncoder", enc);
							pipeline.addLast(new GateTcpHandler());
						}
					});

			b.bind(port).sync();
			// Channel ch = b.bind(port).sync().channel();
			// ch.closeFuture().sync();
		} catch (Exception e) {
			Log.warn(e2s(e));
		} finally {
			// bossGroup.shutdownGracefully();
			// workerGroup.shutdownGracefully();
		}
	}
}
